/**
 * Copyright (c) 2009 blurredVision
 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
 * associated documentation files (the "Software"), to deal in the Software without restriction, 
 * including without limitation the rights to use, copy, modify, merge, publish, distribute, 
 * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is 
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all copies or 
 * substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT 
 * NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 
 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT 
 * OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */
#include "StdAfx.h"
#include "BitmapFont.h"
#include "ResourceFactory.h"
#include "core/core.h"
#include <sstream>

namespace directx {

BitmapFont::BitmapFont(void)
: pSprite(0),
  pDXTexture(0),
  offX(0),
  offY(0)
{
	std::ostringstream sstr;
	sstr << std::endl;
	rowToken = sstr.str();
}

BitmapFont::~BitmapFont(void)
{
	release();
}

void BitmapFont::release()
{
	RELEASE( pSprite );
	//DELETE_POINTER( pDXTexture );
}

void BitmapFont::reset()
{
	DXResource::reset();

	if (bLoaded) {
		load(sFilename, iSize);
	}
}

bool BitmapFont::load(const std::string &image, int size, int style)
{
	sFilename = image;
	iSize = size;
	ITexture *pTexture = coreGetResourceFactory()->loadTexture(image.c_str());

	if (!pTexture)
		return false;

	pDXTexture = dynamic_cast<directx::Texture*>(pTexture);

	if (FAILED( D3DXCreateSprite(pd3dDevice, &pSprite) ))
	{
		coreGetLog()->WriteError("Error creating BitmapFont. Sprite creation failed.", __FILE__, __LINE__);
		return false;
	}
	bLoaded = true;

	if (size == 0)
		iSize = static_cast<int>(pDXTexture->getWidth()/16.0f);

	offX = pDXTexture->getWidth()*0.0625f;
	offY = pDXTexture->getHeight()*0.0625f;

	return true;
}
bool BitmapFont::loadMetrics(const std::string &metrics)
{
	FILE *file;
	memset(&iMetrics, 0, sizeof(iMetrics));
	fopen_s(&file, metrics.c_str(), "rb");
	fseek(file, 17, SEEK_SET); // Skip the first 17 bytes
	fread(&iMetrics, sizeof(char), 256, file);

	fclose(file);
	return false;
}

int BitmapFont::getLength(const std::string &str)
{
	int i;
	int length = 0;
	for (size_t l=0; l<str.size();++l) {
		i  = str.at(l);
		length += iMetrics[i];
	}
	return length;
}

void BitmapFont::print(const std::string &str, int x, int y, int z, int align, int width, int height, const math::Vector4 &color)
{
	float cx, cy;
	RECT rect;
	std::vector<std::string> rows;
	std::string str1;
	int i;
	float size = static_cast<float>(iSize);
	if (align & FONT_CONDENSED) {
		size /= 1.7f;
	}

	// Split the input string into rows
	strsplit(str, rowToken, rows);

	if (pSprite) {
		pSprite->Begin(D3DXSPRITE_ALPHABLEND);

		for (size_t row=0; row<rows.size(); ++row) {
			str1 = rows.at(row);
			if (align & FONT_LEFT) {
				int lastPos = x;
				for (size_t l=0; l<str1.size();++l) {
					i  = str1.at(l);
					cx = pDXTexture->getWidth() * float(i%16)/16.0f;
					cy = pDXTexture->getHeight()* float(i/16)/16.0f;
					rect.left = static_cast<LONG>(cx);
					rect.top = static_cast<LONG>(cy);
					rect.right = static_cast<LONG>(cx+offX);
					rect.bottom = static_cast<LONG>(cy+offY);
					if (FAILED( pSprite->Draw(pDXTexture->getD3DTexture(),
								&rect,
								&D3DXVECTOR3(0, 0, 0),
								&D3DXVECTOR3(static_cast<FLOAT>(lastPos), static_cast<FLOAT>(y+row*iSize), static_cast<FLOAT>(z)),
								D3DCOLOR_COLORVALUE(color.x, color.y, color.z, color.w)) ))
					{
						coreGetLog()->WriteWarning("Failed to draw text", __FILE__, __LINE__);
					}
					lastPos += iMetrics[i];
				}
			}
			else if (align & FONT_RIGHT) {
				int lastPos = x;
				for (int l=static_cast<int>(str1.size()-1); l>=0; --l) {
					i  = str1.at(l);
					lastPos -= (iMetrics[i]+2);
					cx = pDXTexture->getWidth() * float(i%16)/16.0f;
					cy = pDXTexture->getHeight()* float(i/16)/16.0f;
					rect.left = static_cast<LONG>(cx);
					rect.top = static_cast<LONG>(cy);
					rect.right = static_cast<LONG>(cx+offX);
					rect.bottom = static_cast<LONG>(cy+offY);
					if (FAILED( pSprite->Draw(pDXTexture->getD3DTexture(),
								&rect,
								&D3DXVECTOR3(0, 0, 0),
								&D3DXVECTOR3(static_cast<FLOAT>(lastPos), static_cast<FLOAT>(y+row*iSize), static_cast<FLOAT>(z)),
								D3DCOLOR_COLORVALUE(color.x, color.y, color.z, color.w)) ))
					{
						coreGetLog()->WriteWarning("Failed to draw text", __FILE__, __LINE__);
					}
				}
			}
		}

		pSprite->End();
	}
	else {
		coreGetLog()->WriteWarning("BitmapFont is not initialized. Call load() before printing text.", __FILE__, __LINE__);
	}
}

} // namespace
